package com.ltf.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;

@Configuration //将SecurityConfig创建对象放到IOC容器
@EnableWebSecurity //请求先到SecurityConfig 过滤然后才到控制器
//如果是登陆请求，就会找UserDetailsService 的 Bean
public class SecurityConfig { //se cu ri ty  安全的意思
    /**获取认证管理器，简单理解就是比对密码：
    //1.会主动调用 loadUserByUsername(String username) 访问 t_user
    //2.主动比对账号密码
            -成功:successfulAutentication
            -不成功:unsuccessfulAutentication
    */

    @Autowired //获取认证管理器的配置类，再去获取认证管理器
    AuthenticationConfiguration authenticationConfiguration;


    @Bean
    AuthenticationManager authenticationManager() throws Exception {
        return authenticationConfiguration.getAuthenticationManager();
    }

    public SecurityConfig(){
        System.out.println("SecurityConfig 创建对象");
    }

    //There is no PasswordEncoder mapped for the id "null"
    @Bean
    PasswordEncoder passwordEncoder(){
        return new BCryptPasswordEncoder();// 加严加密
    }

    //权限
    @Bean //把http.build() 返回值 装配到IOC容器里面
    SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        //权限判断，是在过滤器的最后一环执行
        //session 有 Autentication 对象
        http.authorizeRequests()
                //无需登录，就可以访问
                .antMatchers("/api/public/**").permitAll()
                .antMatchers("/api/user/**").permitAll()
                //无需登录，就可以访问 token都不需要
                .antMatchers("/api/login").permitAll()
                .antMatchers("/go2login").permitAll()
                //必须是管理员才可以访问
                .antMatchers("/api/adm/**").hasAuthority("adm")
                .antMatchers("/api/fore/tea/**").hasAuthority("tea")
                .antMatchers("/api/fore/stu/**").hasAuthority("stu")
                .anyRequest().authenticated()  //authened 已经登录成功后才能访问 /api/user/改密码
                .and()
                .formLogin()   //  /login
                .permitAll()   //  无需登录可以访问（permit 允许）
                .and()
                .csrf().disable()
        //在这个后面加  不走 Session 走自己的token
        .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
        .and()
                //添加自己的登录方式（api/login2）,并传递 认证管理器
        .addFilter(new JwtLoginFiter(authenticationConfiguration.getAuthenticationManager()))
        //添加自己的授权过滤器,负责拦截每次业务请求
        .addFilter(new JwtAuthenFilter(authenticationConfiguration.getAuthenticationManager()))
                //登录异常
        .exceptionHandling().authenticationEntryPoint(new JwtAuthEntryPoint())
                //访问授权异常
        .accessDeniedHandler(new JwtAccessDeniedHandler());

        return http.build();
    }

    //用户信息，内存用户信息
    //UserDetailsService  User 用户 Details 具体信息  Service  服务
//    @Bean
//    UserDetailsService userDetailsService(){
//
//    }
}
